package com.hd.service.activiti.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hd.dao.BaseDao;
import com.hd.entity.activiti.ElementDef;
import com.hd.entity.activiti.UserTask;
import com.hd.service.activiti.ElementDefService;
import com.hd.service.activiti.UserTaskService;
@Service("userTaskService")
public class UserTaskServiceImpl implements UserTaskService {
	@Autowired
	private BaseDao<UserTask, String> userTaskDao;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private ElementDefService elementDefService;
	@Autowired
	private HistoryService historyService;
	/**
	 * 保存
	 */
	@Override
	public Serializable save(UserTask userTask) {
		userTask.setId(UUID.randomUUID().toString());
		return userTaskDao.save(userTask);
	}
	/**
	 * 修改
	 */
	@Override
	public void update(UserTask userTask) {
		userTaskDao.update(userTask);

	}

	/**
	 * 刪除
	 */
	@Override
	public void delete(UserTask userTask) {
		userTaskDao.delete(userTask);
	}

	/**
	 * 清空表
	 */
	@Override
	public void deleteAll() {
		String hql = "delete from UserTask";
		userTaskDao.execute(hql);
	}

	/**
	 * 查询一条数据
	 */
	@Override
	public UserTask findById(String id) {
		return userTaskDao.get(UserTask.class, id);
	}
	
	/**
	 * 根据流程定义ID查询用戶任务
	 */
	@Override
	public List<UserTask> findByWhere(String procDefId) {
		String hql = "from UserTask where procDefId=? order by seq asc";
		System.out.println(procDefId);
		return userTaskDao.find(hql, procDefId);
	}
	
	/**
	 * 查询所有
	 */
	@Override
	public List<UserTask> getAll() {
		String hql = "from UserTask where 1=1 order by seq asc";
		return userTaskDao.find(hql);
	}
	
	/**
	 * 初始化任务节点
	 */
	@Override
	public void initTaskNode() {
		// 清空任务表
		this.deleteAll();
		List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
				.orderByDeploymentId().desc().list();
		// 读取节点保存节点
		for (ProcessDefinition processDefinition : processDefinitions) {
			setActivitiNode(processDefinition);
		}
	}
	
	/**
	 * 初始化单个流程
	 */
	@Override
	public void loadSingleBpmn(String processDefinitionId) {
		//初始化流程节点
		elementDefService.init(processDefinitionId);
		ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
		if (processDefinition != null) {
			setActivitiNode(processDefinition);
		}

	}

	private void setActivitiNode(ProcessDefinition processDefinition) {
		BpmnModel model = repositoryService.getBpmnModel(processDefinition.getId());
		if(model != null) {
			 int i=1;
		    Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements();
		    for(FlowElement e : flowElements) {
		    	if(e.getClass().getName().toString().equals("org.activiti.bpmn.model.UserTask")) {
							String taskDefKey=e.getId();
							String taskName=e.getName();
					String hql="from UserTask where procDefId=? and taskDefKey=?";
					List<UserTask>userTasks=userTaskDao.find(hql, processDefinition.getId(),taskDefKey);
					if(userTasks.size()>0) {
						UserTask userTask=userTasks.get(0);
						userTask.setTaskName(taskName);
						userTaskDao.update(userTask);
					}else {
						UserTask userTask=new UserTask();
						userTask.setId(UUID.randomUUID().toString());
						userTask.setTaskDefKey(taskDefKey);
						userTask.setTaskName(taskName);
						userTask.setProcDefKey(processDefinition.getKey());
						userTask.setProcDefId(processDefinition.getId());
						userTask.setProcDefName(processDefinition.getName());
						userTask.setVersion(""+processDefinition.getVersion());
						userTask.setSeq(i);
						userTaskDao.save(userTask);
					}
					i++;
							
		        }
		    }
		}
	}
	/**
	 * 此方法有问题，对于多实例会出现问题，无法保存
	 * @param
	 */
	/*private void setActivitiNode(ProcessDefinition processDefinition) {
		String proDefKey = processDefinition.getKey();
		List<UserTask> userTasks = this.findByWhere(proDefKey);
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService
				.getProcessDefinition(processDefinition.getId());
		List<ActivityImpl> activityList = processDefinitionEntity.getActivities();// 获取当前任务的所有节点
		for (ActivityImpl activity : activityList) {
			ActivityBehavior activityBehavior = activity.getActivityBehavior();
			System.out.println("-------"+activity.getProperty("name"));
			boolean isFound = false;
			// 是否为用户任务
			if (activityBehavior instanceof UserTaskActivityBehavior) {
				UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
				TaskDefinition taskDefinition = userTaskActivityBehavior.getTaskDefinition();
				// 任务所属角色
				String taskDefKey = taskDefinition.getKey();
				System.out.println(">>"+taskDefKey);
				Expression taskName = taskDefinition.getNameExpression();
				// 判断表中是否存在此节点
				if (userTasks.size() != 0) {
					for (UserTask userTask : userTasks) {
						if (taskDefKey.equals(userTask.getTaskDefKey())) {
							userTask.setProcDefKey(processDefinition.getKey());
							userTask.setProcDefName(processDefinition.getName());
							userTask.setTaskDefKey(taskDefKey);
							userTask.setTaskName(taskName.toString());
							this.update(userTask);
							isFound = true;
							break;
						}
					}
				}
				if (!isFound) {
					UserTask userTask = new UserTask();
					userTask.setProcDefKey(processDefinition.getKey());
					userTask.setProcDefName(processDefinition.getName());
					userTask.setTaskDefKey(taskDefKey);
					userTask.setTaskName(taskName.toString());
					this.save(userTask);
				}
			}
		}

	}*/

	@Override
	public UserTask getUserTaskByParams(String procDefId, String taskDefKey) {
		String hql = "from UserTask where procDefId=? and taskDefKey=?";
		List<UserTask> userTasks = userTaskDao.find(hql, procDefId,taskDefKey);
		if(userTasks.size()>0) {
			return userTasks.get(0);
		}
		return null;
	}
	
	/**
	 * 回退节点
	 */
	@Override
	public List<ElementDef> getFallBackElements(String processInstanceId) {
		List<HistoricActivityInstance> his = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
		String processDefId="";
		if(his.size()>0) {
			processDefId=his.get(0).getProcessDefinitionId();
		}
		List<ElementDef> elementDefs = elementDefService.find(processDefId);
		List<ElementDef>newElementDefs=new ArrayList<>();
		for(HistoricActivityInstance hi:his) {
			if(hi.getEndTime()!=null) {
				for(ElementDef e:elementDefs) {
					if(e.getKey().equals(hi.getActivityId())) {
						newElementDefs.add(e);
					}
				}
			}
		}
		return newElementDefs;
	}
	@Override
	public List<ElementDef> getForwardElements(String processInstanceId) {
		List<HistoricActivityInstance> his = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
		String processDefId="";
		if(his.size()>0) {
			processDefId=his.get(0).getProcessDefinitionId();
		}
		List<ElementDef> elementDefs = elementDefService.find(processDefId);
		List<ElementDef>newElementDefs=new ArrayList<>();
		Set<String>key1Set=new HashSet<String>();
		Set<String>key2Set=new HashSet<String>();
		for(ElementDef e:elementDefs) {
			key1Set.add(e.getKey());
		}
		return newElementDefs;
	}
}
